#!/usr/bin/env python3
"""Error classes used by simplejson"""

__all__ = ["JSONDecodeError"]


def linecol(doc, pos):
  lineno = doc.count("\n", 0, pos) + 1
  if lineno == 1:
    colno = pos + 1
  else:
    colno = pos - doc.rindex("\n", 0, pos)
  return lineno, colno


def errmsg(msg, doc, pos, end=None):
  lineno, colno = linecol(doc, pos)
  msg = msg.replace("%r", repr(doc[pos : pos + 1]))
  if end is None:
    fmt = "%s: line %d column %d (char %d)"
    return fmt % (msg, lineno, colno, pos)
  endlineno, endcolno = linecol(doc, end)
  fmt = "%s: line %d column %d - line %d column %d (char %d - %d)"
  return fmt % (msg, lineno, colno, endlineno, endcolno, pos, end)


class JSONDecodeError(ValueError):
  """Subclass of ValueError with the following additional properties:

  msg: The unformatted error message
  doc: The JSON document being parsed
  pos: The start index of doc where parsing failed
  end: The end index of doc where parsing failed (may be None)
  lineno: The line corresponding to pos
  colno: The column corresponding to pos
  endlineno: The line corresponding to end (may be None)
  endcolno: The column corresponding to end (may be None)

  """

  # Note that this exception is used from _speedups
  def __init__(self, msg, doc, pos, end=None):
    ValueError.__init__(self, errmsg(msg, doc, pos, end=end))
    self.msg = msg
    self.doc = doc
    self.pos = pos
    self.end = end
    self.lineno, self.colno = linecol(doc, pos)
    if end is not None:
      self.endlineno, self.endcolno = linecol(doc, end)
    else:
      self.endlineno, self.endcolno = None, None

  def __reduce__(self):
    return self.__class__, (self.msg, self.doc, self.pos, self.end)
